package com.naiterui.ehp.bs.doctor.service.user.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.esign.DigitalCertificateBO;
import com.naiterui.ehp.bp.bo.esign.EsignNoSecretBO;
import com.naiterui.ehp.bp.bo.esign.NoSecretParamBO;
import com.naiterui.ehp.bp.bo.esign.PreSignResultBO;
import com.naiterui.ehp.bp.bo.esign.WillTypeBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bp.utils.sms.SMSUtil;
import com.naiterui.ehp.bs.doctor.dao.IDoctorDao;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.fegin.EsignFeginClient;
import com.naiterui.ehp.bs.doctor.service.user.IEsignUserService;
import com.naiterui.ehp.bs.doctor.service.user.ILicenceService;
import com.naiterui.ehp.bs.doctor.utils.ChackPasswordUtils;
import com.naiterui.ehp.bs.doctor.utils.PropertyValueConstants;
import com.naiterui.ehp.bs.doctor.vo.IdCardVO;
import com.naiterui.ehp.bs.doctor.vo.sign.WillTypeVO;

/**
 * @Description 电子签名
 * @Author gongbaoqiang
 * @Date 2020/6/8 3:50 PM
 */
@Service
public class AdDoctorEsignUserServiceImpl implements IEsignUserService {

    @Autowired
    private IDoctorDao doctorDao;


    @Autowired
    private ILicenceService licenceService;

    @Autowired
    private EsignFeginClient esignFeginClient;

    @Override
    public void getRealnameCode(Long doctorId) throws BusinessException {
        Doctor doctor = this.getDoctor(doctorId);
        IdCardVO idCard = licenceService.getIdCardByDoctor(doctorId);
        if (idCard == null) {
            throw new BusinessException(ExceptionCodes.PRESCRIPTION_SIGN_DOCTOR_NOT_RECORD_ERROR);
        }
        esignFeginClient.getRealnameCode(doctor.getName(), doctor.getPhone(), idCard.getNumber());
    }

    @Override
    public void checkRealnameCode(Long doctorId, String code) throws BusinessException {
        Doctor doctor = this.getDoctor(doctorId);
        //实名验证，实名状态由签名服务维护
        Boolean checkRealnameByCode = esignFeginClient.checkRealnameByCode(doctor.getPhone(), code);
        if (checkRealnameByCode) {
            // 认证通过后改为认证中和备案中
            doctor.setStatus(Doctor.AUTH_STATUS_AUDITING);
            doctor.setRecordStatus(Doctor.RECORD_STATUS_EXAMINEING);
            doctorDao.update(doctor);
        }
    }

    @Override
    public List<WillTypeVO> getWillTypes(Long doctorId) throws BusinessException {
        List<WillTypeBO> bos = esignFeginClient.getWillTypes(doctorId);
        return BeanUtil.copyList(bos, new ArrayList<>(), WillTypeVO.class);
    }

    @Override
    public void updateWillType(Long doctorId, String willType) throws BusinessException {
        esignFeginClient.updateWillType(doctorId, willType);
    }

    @Override
    public void updatePassword(Long doctorId, String passwd, String code) throws BusinessException {
       Doctor doctor = this.getDoctor(doctorId);
        //校验验证码码
        String redisKey = PropertyValueConstants.PHONE_ESIGN_PWD_KEY + doctor.getPhone();
        SMSUtil.validCode(code, redisKey, CommonConstant.REDIS_PRE_PHARMACIST);

        //密码解密
        String pwd = ChackPasswordUtils.decryptPasswd(passwd);

        esignFeginClient.updatePasswd(doctorId, pwd);

        //缓存医生设置密码状态
        String statusKey = PropertyValueConstants.DOCTOR_ESIGN_PWD_STATUS_KEY + doctorId;
        RedisUtil.valueOps().set(statusKey, true);
    }

    @Override
    public Boolean passwordStatus(Long doctorId) throws BusinessException{
        String statusKey = PropertyValueConstants.DOCTOR_ESIGN_PWD_STATUS_KEY + doctorId;
        return RedisUtil.valueOps().getObject(statusKey) == null ? false : true;
    }

    @Override
    public EsignNoSecretBO getNoSecretByDoctorId(Long doctorId) throws BusinessException {
        Integer noSecret = esignFeginClient.getNoSecret(doctorId);
        EsignNoSecretBO noSecretBO = new EsignNoSecretBO();
        if(noSecret == 0){
            noSecretBO.setNoSecret(false);
        } else {
            noSecretBO.setNoSecret(true);
            noSecretBO.setNotRemind(false);
            return noSecretBO;
        }
        boolean existsKey = RedisUtil.keyOps().existsKey(CommonConstant.DR_NO_SECRET_REMIND + doctorId);
        if(existsKey){
            noSecretBO.setNotRemind(false);
        }else {
            noSecretBO.setNotRemind(true);
        }
        return noSecretBO;
    }

    @Override
    public PreSignResultBO preNoSecret(Long doctorId) throws BusinessException {
        return esignFeginClient.preNoSecret(doctorId);
    }

    @Override
    public void setNoSecret(Long doctorId, Boolean noSecret, String authPwd, String uniqueId) throws BusinessException {
        esignFeginClient.setNoSecret(NoSecretParamBO.builder().signUserId(doctorId).noSecret(noSecret).authPwd(authPwd)
            .uniqueId(uniqueId).build());
    }

    @Override
    public DigitalCertificateBO getDigitalCertificate(Long doctorId) throws BusinessException {
        return esignFeginClient.getDigitalCertificate(doctorId);
    }

    private Doctor getDoctor(Long doctorId) throws BusinessException {
        Doctor doctor = doctorDao.get(doctorId);
        // 医生不存在
        if (doctor == null) {
            throw new BusinessException(ExceptionCodes.USER_NOT_EXIST);
        }

        // 账户是否被禁用
        if (doctor.getAccountStatus() == 1) {
            throw new BusinessException(ExceptionCodes.USER_NOT_NOMAL);
        }
        return doctor;
    }



}
